﻿using NotesApp.Commands;
using NotesApp.Helpers;
using NotesApp.Models;
using NotesApp.Repositories;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;

namespace NotesApp.ViewModels
{
    public delegate void delegateRequestCardList(Folder folder);
    public class IndexViewModel : BaseViewModel, IDisposable
    {
        #region Properties
        public ObservableCollection<Folder> Folders { get; set; }
        private NoteRepository _noteRepository;
        public delegateRequestCardList CardListRequest;
        private readonly IWindowService _windowService;

        public Folder SelectedFolder { get => GetProperty<Folder>(); set => SetProperty(value); }
        #endregion
        #region ctor
        public IndexViewModel(IWindowService windowService)
        {
            this._windowService = windowService;
            _noteRepository = new NoteRepository();

            ItemDoubleClickCommand = new RelayCommand(OnItemDoubleClick);
            EditCommand = new RelayCommand(EditClicked, CanEdit);
            SaveTagCommand = new RelayCommand(SaveTagClickedAsync, CanSave);
            AddTagCommand = new RelayCommand(AddTagClickedAsync);
            DeleteCommand = new RelayCommand(DeleteClickedAsync, CanDelete);

            InitializeAsync();
            LoadFoldersAsync().ConfigureAwait(false);
        }
        #endregion
        #region Methods

        private async Task InitializeAsync()
        {
            await DatabaseHelper.InitializeDatabaseAsync();
        }

        private async Task LoadFoldersAsync()
        {
            try
            {
                var folders = await _noteRepository.GetAllFoldersAsync();
                foreach (var folder in folders)
                {
                    folder.SetOwner(this);
                }
                Folders = new ObservableCollection<Folder>(folders);
                Trace.WriteLine($"Folders collection updated on UI thread: {Folders?.Count}");
            }
            catch (Exception ex)
            {
                Debug.WriteLine($"Error loading folders: {ex.Message}");
                _windowService.ShowError("Error loading folders", ex.Message);
            }
        }

        private bool CanDelete(object arg) => SelectedFolder != null;

        private async void DeleteClickedAsync(object obj)
        {
            if (SelectedFolder == null) return;

            try
            {
                await _noteRepository.DeleteTagAsync(SelectedFolder.Id);
                Folders.Remove(SelectedFolder);
                SelectedFolder = null;
            }
            catch (Exception ex)
            {
                Debug.WriteLine($"Error deleting tag: {ex.Message}");
                _windowService.ShowError("Error deleting tag", ex.Message);
            }
        }

        private async void AddTagClickedAsync(object obj)
        {
            try
            {
                var newTag = new Tag { Name = "New Tag" };
                await _noteRepository.AddTagAsync(newTag);
                var folder = new Folder { Id = newTag.ID, Name = newTag.Name, IsEditing = true };
                folder.SetOwner(this);
                Folders.Add(folder);
            }
            catch (Exception ex)
            {
                Debug.WriteLine($"Error adding tag: {ex.Message}");
                _windowService.ShowError("Error adding tag", ex.Message);
            }
        }

        private bool CanSave(object arg) => SelectedFolder != null && ValidateTagName(SelectedFolder);

        private bool CanEdit(object arg) => SelectedFolder != null;

        public bool ValidateTagName(Folder folder)
        {
            return !Folders.Any(f => f != folder && f.Name == folder.Name);
        }

        private async void SaveTagClickedAsync(object obj)
        {
            if (!(obj is Folder folder)) return;

            if (!ValidateTagName(folder))
            {
                _windowService.ShowWarning("Invalid Tag Name", $"The name '{folder.Name}' already exists.");
                folder.Name = folder.OriginName;
                return;
            }

            try
            {
                var tag = new Tag { ID = folder.Id, Name = folder.Name };
                await _noteRepository.UpdateTagAsync(tag);
            }
            catch (Exception ex)
            {
                Debug.WriteLine($"Error updating tag: {ex.Message}");
                _windowService.ShowError("Error updating tag", ex.Message);
            }
        }

        private void EditClicked(object obj)
        {
            if (!(obj is Folder selectedFolder)) return;

            var folder = Folders.FirstOrDefault(f => f.Id == selectedFolder.Id);
            if (folder != null)
            {
                folder.OriginName = folder.Name;
                folder.IsEditing = true;
            }
        }

        public void OnItemDoubleClick(object parameter)
        {
            EditCommand?.Execute(parameter);
        }

        public void OpenSelecteFolder(object parameter)
        {
            if (parameter is Folder selectedItem)
            {
                CardListRequest?.Invoke(selectedItem);
                _windowService.CloseWindow();
            }
        }
        public async void Save()
        {
            // 这里可以实现保存逻辑，例如保存所有文件夹和标签到数据库
            foreach (var folder in Folders)
            {
                if (folder.Id > 0) // 已存在的标签
                {
                    await _noteRepository.UpdateTagAsync(new Tag { ID = folder.Id, Name = folder.Name });
                }
                //else // 新标签
                //{
                //    var newTag = new Tag { Name = folder.Name };
                //    await _noteRepository.AddTagAsync(newTag); // 使用添加方法
                //    folder.Id = newTag.ID; // 更新文件夹的 ID
                //}
            }
        }
        public void Dispose()
        {
            // Dispose of unmanaged resources here
        }
        #endregion

        #region Commands
        public ICommand ItemDoubleClickCommand { get; set; }
        public ICommand RenameCommand { get; set; }
        public ICommand EditCommand { get; set; }
        public ICommand SaveTagCommand { get; set; }
        public ICommand FilterCommand { get; set; }
        public ICommand AddTagCommand { get; set; }
        public ICommand DeleteCommand { get; set; }
        #endregion

    }

    public interface IWindowService
    {
        void ShowError(string title, string message);
        void ShowWarning(string title, string message);
        void CloseWindow();
    }
}
